﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.FxCop.Sdk;

namespace RulesByImaginaryDevelopment
{

    //http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.aspx
    //http://msdn.microsoft.com/en-us/library/system.data.entity.dbcontext.aspx

    /// <summary>
    /// Meant to prevent you from defining public non-interface members on a context
    /// </summary>
    public class ContextMembersMustNotBePublic : BaseRule
    {
        public ContextMembersMustNotBePublic() : base("ContextMembersMustNotBePublic") { }

        public override TargetVisibilities TargetVisibility
        {
            get
            {
                return TargetVisibilities.ExternallyVisible;
            }
        }

        public override ProblemCollection Check(Member member)
        {
            if (member.IsPublic == false || member.DeclaringType==null || member.DeclaringType.BaseType==null || member.DeclaringType.BaseType==FrameworkTypes.Object)
                return Problems;
            return CheckRecursive(member, member.DeclaringType);
            //FrameworkAssemblies.SystemData.GetType("System.Data.Objects", "ObjectContext");
            
        }

        private ProblemCollection CheckRecursive(Member member, TypeNode typeNode)
        {
            Func<string, bool> MatchesNodeName = s => typeNode.FullName == s;
            if(typeNode==null)
                return Problems;
            if(member.Name.Name.Contains(".ctor"))
                return Problems;
            if (member.DeclaringType.FullName!=typeNode.FullName  && (
                    MatchesNodeName("System.Data.Objects.ObjectContext") ||
                   MatchesNodeName ( "System.Data.Entity.DbContext") ||
                   MatchesNodeName("System.Data.Linq.DataContext")))
                Problems.Add(new Problem(new Resolution(format:"Make {0} internal in {1}",arguments: new[]{member.Name.Name,member.DeclaringType.Name.Name}),member));
            //else
            //{
            //    Problems.Add(new Problem(new Resolution(typeNode.FullName + "." + member.FullName), member));
            //}
            return CheckRecursive(member, typeNode.BaseType);
        }
       
    }
}
